use std::ptr;
use std::fs;
use winapi::um::synchapi::{CreateMutexW, ReleaseMutex};
use winapi::um::handleapi::CloseHandle;
use winapi::um::errhandlingapi::GetLastError;
use winapi::shared::winerror::ERROR_ALREADY_EXISTS;
use winapi::um::winreg::{RegCreateKeyExW, RegSetValueExW, RegCloseKey, RegQueryValueExW, HKEY_CURRENT_USER};
use winapi::um::winnt::{KEY_WRITE, KEY_READ, REG_SZ};
use std::os::windows::ffi::OsStrExt;
use std::ffi::OsStr;
use dirs::home_dir;

pub struct SingleInstance {
    mutex_handle: *mut winapi::ctypes::c_void,
    app_name: String,
}

impl Clone for SingleInstance {
    fn clone(&self) -> Self {
        Self {
            mutex_handle: ptr::null_mut(),
            app_name: self.app_name.clone(),
        }
    }
}

impl SingleInstance {
    pub fn new(app_name: &str) -> Result<Self, Box<dyn std::error::Error>> {
        let mutex_name = format!("Global\\{}", app_name);
        let wide_name: Vec<u16> = mutex_name.encode_utf16().chain(std::iter::once(0)).collect();
        
        unsafe {
            let handle = CreateMutexW(ptr::null_mut(), 0, wide_name.as_ptr());
            
            if handle.is_null() {
                return Err("无法创建互斥锁".into());
            }
            
            let error = GetLastError();
            if error == ERROR_ALREADY_EXISTS {
                CloseHandle(handle);
                return Err("程序已在运行，已发送新参数".into());
            }
            
            Ok(SingleInstance { mutex_handle: handle, app_name: app_name.to_string() })
        }
    }
    
    pub fn set_auto_start(&self, enable: bool) -> Result<(), Box<dyn std::error::Error>> {
        let key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
        let app_name = "im-select-ms";
        
        let wide_key_path: Vec<u16> = OsStr::new(key_path).encode_wide().chain(std::iter::once(0)).collect();
        let wide_app_name: Vec<u16> = OsStr::new(app_name).encode_wide().chain(std::iter::once(0)).collect();
        
        unsafe {
            let mut key_handle = ptr::null_mut();
            let result = RegCreateKeyExW(
                HKEY_CURRENT_USER,
                wide_key_path.as_ptr(),
                0,
                ptr::null_mut(),
                0,
                KEY_WRITE,
                ptr::null_mut(),
                &mut key_handle,
                ptr::null_mut()
            );
            
            if result != 0 {
                return Err("无法创建注册表项".into());
            }
            
            if enable {
                // 获取当前可执行文件路径
                let exe_path = std::env::current_exe()?.to_string_lossy().to_string();
                let wide_exe_path: Vec<u16> = OsStr::new(&exe_path).encode_wide().chain(std::iter::once(0)).collect();
                
                let result = RegSetValueExW(
                    key_handle,
                    wide_app_name.as_ptr(),
                    0,
                    REG_SZ,
                    wide_exe_path.as_ptr() as *const u8,
                    (wide_exe_path.len() * 2) as u32
                );
                
                if result != 0 {
                    RegCloseKey(key_handle);
                    return Err("无法设置开机自启动".into());
                }
            } else {
                // 删除自启动项
                let result = RegSetValueExW(
                    key_handle,
                    wide_app_name.as_ptr(),
                    0,
                    REG_SZ,
                    ptr::null(),
                    0
                );
                
                if result != 0 {
                    RegCloseKey(key_handle);
                    return Err("无法删除开机自启动".into());
                }
            }
            
            RegCloseKey(key_handle);
        }
        
        Ok(())
    }

    pub fn is_auto_start_enabled(&self) -> Result<bool, Box<dyn std::error::Error>> {
        let key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Run";
        let app_name = "im-select-ms";
        
        let wide_key_path: Vec<u16> = OsStr::new(key_path).encode_wide().chain(std::iter::once(0)).collect();
        let wide_app_name: Vec<u16> = OsStr::new(app_name).encode_wide().chain(std::iter::once(0)).collect();
        
        unsafe {
            let mut key_handle = ptr::null_mut();
            let result = RegCreateKeyExW(
                HKEY_CURRENT_USER,
                wide_key_path.as_ptr(),
                0,
                ptr::null_mut(),
                0,
                KEY_READ,
                ptr::null_mut(),
                &mut key_handle,
                ptr::null_mut()
            );
            
            if result != 0 {
                return Err("无法打开注册表项".into());
            }
            
            let mut value_type = 0u32;
            let mut value_size = 0u32;
            
            // 查询值的大小
            let result = RegQueryValueExW(
                key_handle,
                wide_app_name.as_ptr(),
                ptr::null_mut(),
                &mut value_type,
                ptr::null_mut(),
                &mut value_size
            );
            
            RegCloseKey(key_handle);
            
            if result == 0 && value_size > 0 {
                Ok(true)
            } else {
                Ok(false)
            }
        }
    }
}

impl Drop for SingleInstance {
    fn drop(&mut self) {
        unsafe {
            if !self.mutex_handle.is_null() {
                ReleaseMutex(self.mutex_handle);
                CloseHandle(self.mutex_handle);
            }
        }
    }
} 